#!/usr/bin/env php
<?php
// +----------------------------------------------------------------------
// | server.php [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016-2017 limingxinleo All rights reserved.
// +----------------------------------------------------------------------
// | Author: limx <715557344@qq.com> <https://github.com/limingxinleo>
// +----------------------------------------------------------------------

define('ROOT_PATH', __DIR__);
define('APP_PATH', ROOT_PATH . '/app');
define('IS_CLI', false);
define('ENGINE', 'SWOOLE');

use Phalcon\Config;
use Phalcon\Mvc\Application;
use Phalcon\Di\FactoryDefault;
use App\Core\Http\Request\SwooleRequest;
use App\Core\Http\Response\SwooleResponse;
use App\Core\Exception\Handler;

$script = $argv[0];
if (empty($argv[1])) {
    echo './server [start|restart|reload|stop|status]' . PHP_EOL;
    exit;
}

$action = $argv[1];

/**
 * Get config service for use in inline setup below
 */
/** @var Config $config */
$config = include APP_PATH . "/config/config.php";

$pidDir = $config->path('application.pidsDir', ROOT_PATH . '/');
$logDir = $config->path('application.logDir', ROOT_PATH . '/');
$host = $config->path('swoole.http.host', '0.0.0.0');
$port = $config->path('swoole.http.port', 8080);

$pidFile = $pidDir . 'swoole_http_server.pid';
$logFile = $logDir . 'swoole_http_server.log';

$pid = 0;
if (file_exists($pidFile)) {
    $pid = intval(file_get_contents($pidFile));
    if (!swoole_process::kill($pid, 0)) {
        $pid = 0;
    }
}

switch ($action) {
    case 'restart':
        if ($pid > 0) {
            swoole_process::kill($pid);
            while (swoole_process::kill($pid, 0)) {
            }
        }
    // no break
    case 'start':
        $http = new swoole_http_server($host, $port);
        $http->set([
            'dispatch_mode' => $config->path('swoole.http.dispatchMode', 3),
            'worker_num' => $config->path('swoole.http.workerNum', 4),
            'max_request' => $config->path('swoole.http.maxRequest', 10000),
            'log_file' => $logFile,
            'log_level' => $config->path('swoole.http.logLevel', 5),
            'pid_file' => $pidFile,
            'open_tcp_nodelay' => $config->path('swoole.http.openTcpNodelay', 1),
            'daemonize' => $config->path('swoole.http.daemonize', 0),
        ]);
        $http->on('workerStart', function () {
            /** @var FactoryDefault $di */
            require ROOT_PATH . '/bootstrap/bootstrap.php';
            // TODO: 为解决Mysql长期闲置，连接被释放的问题，可以在这里进行Mysql定时续约

        });
        $http->on('request', function ($request, $response) {
            $di = FactoryDefault::getDefault();
            /** @var SwooleRequest $SRequest */
            $SRequest = di('request');
            $SRequest->init($request);

            $application = new Application($di);
            $uri = $SRequest->get('_url', null, '/');

            /** @var SwooleResponse $SResponse */
            $SResponse = di('response');
            $SResponse->init($response);

            try {
                $application->handle($uri)->send();
            } catch (Exception $ex) {
                Handler::getInstance()->render($ex);
            }
        });
        echo 'swoole http server start.' . PHP_EOL;
        $http->start();
        break;
    case 'reload':
        if ($pid > 0 && swoole_process::kill($pid, SIGUSR1)) {
            echo 'swoole http server reload successed.' . PHP_EOL;
        } else {
            echo 'swoole http server is not running' . PHP_EOL;
        }
        break;
    case 'stop':
        if ($pid > 0 && swoole_process::kill($pid)) {
            echo 'swoole http server stop successed.' . PHP_EOL;
        } else {
            echo 'swoole http server is not running' . PHP_EOL;
        }
        break;
    case 'status':
        if ($pid > 0) {
            echo 'swoole http server is running. master pid is ' . $pid . PHP_EOL;
        } else {
            echo 'swoole http server is not running' . PHP_EOL;
        }
        break;
}
